/*
 * @Author: 9ilk 3535851673@qq.com
 * @Date: 2025-03-18 20:37:34
 * @LastEditors: 9ilk 3535851673@qq.com
 * @LastEditTime: 2025-03-19 23:08:05
 * @FilePath: /zhuang/ETEpollServer/Listener.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once
 #include <iostream>
 #include <memory>
 #include "Epoller.hpp"
 #include "InetAddr.hpp"
 #include "Socket.hpp"
 #include "Log.hpp"
 #include "Connection.hpp"
 #include "IOService.hpp"
 #include "Reactor.hpp"
 #include "Protocol.hpp"
 #include "Calculator.hpp"
using namespace SocketModule;
using namespace LogModule;
using namespace std;
// 专门负责获取链接的模块
// 链接管理器

class Listener : public Connection
{
public:
  Listener(int port)
      : _listensock(std::make_unique<TcpSocket>()),
        _port(port)
  {
      _listensock->BuildTcpSocket(_port);//创建套接字
      SetSockfd(_listensock->Fd());
      SetEvents(EPOLLIN|EPOLLET);
  }

  ~Listener()
  {
    _listensock->Close(); // 关闭套接字
  }

  virtual void Sender() override
  {

  }

  virtual void Recver() override // 获取新连接
  {
    LOG(LogLevel::DEBUG) << "into Listen Recv..\n";
    // 读就绪 listensockfd就绪
    // IO处理 --- 获取新连接
    // 你怎么知道出来的就是一个连接
    while (true)
    {

      InetAddr peer;
      int aerrno = 0;
      int sockfd = _listensock->Accepter(&peer, &aerrno);
      if (sockfd > 0)
      { // success
        //获取新连接之后我们不能直接读取需要将sockfd添加到epoll，而epollServer只认识Connection
        LOG(LogLevel::DEBUG) << "Accepter success: "<< sockfd;
        //普通的文件描述符，处理IO的也是Connection
        //1.设置文件描述符非阻塞
        SetNonBlock(sockfd);
        //2.sockfd包装成Connection
        auto conn = make_shared<IOService>(sockfd);
        conn->RegisterMessage(HandlerRequest); //注册处理收到消息的业务
        //3.插入到EpollServer
        GetOwner()->InsertConnection(conn); //这里就使用了owner指针
      }
      else
      { // 错误判断
        if (aerrno == EAGAIN || aerrno == EWOULDBLOCK)
        {
          LOG(LogLevel::DEBUG) << "accept all connect.. done\n";
          break;
        }
        else if (aerrno == EINTR) // 中断 重新读取
        {
          LOG(LogLevel::DEBUG) << "accepter intr by signal,continue...\n";
          continue;
        }
        else
        {
          LOG(LogLevel::WARNING) << "accept error...\n";
        }
      }
    }
    ///
  }

  virtual void Excepter() override 
  {

  }

  int Sockfd()
  {
    return _listensock->Fd();
  }

private:
  unique_ptr<Socket> _listensock;
  int _port;
};
